﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ecdl.demo.model;
using ecdl.demo.model.expression;
using Ninject;
using DocumentFormat.OpenXml.Packaging;
using ecdl.demo.persistence;
using ecdl.demo.model.file;
using System.Xml.Serialization;
using ecdl.demo.model.precondition;

namespace ecdl.demo.model.word {
    public class WordTask : ITask {

        private ITaskPresenter taskPresenter;
        private IDocxLoader docxLoader;
        private IVolumeProvider pathProvider;

        public WordTask() {
        }

        [Inject]
        public WordTask(ITaskPresenter taskPresenter, IDocxLoader docxLoader, IVolumeProvider pathProvider) {
            this.taskPresenter = taskPresenter;
            this.docxLoader = docxLoader;
            this.pathProvider = pathProvider;
        }

        public string Text { get; set; }

        public string FileNameDocx { get; set; }

        public bool AutoSave { get; set; }

        public List<Precondition> Preconditions { get; set; }

        public ITaskEvaluation Evaluate() {
            //create the context (the for the expression)
            SaveIfNecessary();
            WordprocessingDocument document = null;
            try {
                document = docxLoader.ReadDocument(FileNameDocx);
                ExpressionContext context = new ExpressionContext(document);
                ExpressionState state = Expression.Evaluate(context);
                return TaskEvaluation.CreateFromExpressionState(this, state);

            } catch (Exception e) {
                return new TaskEvaluation(this, 0, e.Message);
            } finally {
                if (document != null)
                    document.Close();
            }
        }

        private void SaveIfNecessary() {
            if (AutoSave) {
                WordDocumentSaver saver = new WordDocumentSaver();
                saver.SaveDocument(pathProvider.GetFullPath(FileNameDocx));
            }
        }

        public int MaxPoints { get; set; }

        public bool CanSubmit {
            get { return true; }
        }

        public Expression Expression { get; set; }

        public void Activate() {
            taskPresenter.HidePresenter();
        }

        public void InitializePreconditions() {
            foreach (var preCondition in Preconditions) {
                preCondition.Execute(pathProvider.GetPath());
            }
        }
    }

    public class WordTaskDTO : TaskDTO {
        public WordTaskDTO() {
            Preconditions = new List<Precondition>();
        }
        
        [XmlAttribute("autosave")]
        public bool AutoSave { get; set; }
        [XmlAttribute("docx")]
        public string FileNameDocx { get; set; }
        public ExpressionDTO Expression { get; set; }
        public List<Precondition> Preconditions { get; set; }

        public override ITask ToModel(ModelFactory factory) {
            WordTask task = factory.CreateModel<WordTask>();
            task.Text = Text;
            task.FileNameDocx = FileNameDocx;
            task.Expression = Expression.ToModel(factory);
            task.MaxPoints = MaxPoints;
            task.Preconditions = Preconditions;
            task.AutoSave = AutoSave;
            return task;
        }
    }
}
